﻿// -----------------------------------------------------------------------
// Copyright (c) David Kean. All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Text;
using System.Threading;
using Moq;
using Moq.Protected;

namespace Portable
{
    public class IDisposableFactory
    {
        public static T OverrideDispose<T>(Action action)
           where T : class, IDisposable
        {
            var mock = CreateMock<T>(null);
            mock.Setup(m => m.Dispose())
               .Callback(action);

            return mock.Object;
        }

        public static T OverrideDispose<T>(Action<bool> action)
           where T : class, IDisposable
        {
            return OverrideDispose<T>((object)null, action);
        }

        public static T OverrideDispose<T>(object constructorArgument, Action<bool> action)
            where T : class, IDisposable
        {
            var mock = CreateMock<T>(constructorArgument);
            mock.Protected().Setup("Dispose", ItExpr.IsAny<bool>())
               .Callback(action);

            return mock.Object;
        }

        private static Mock<T> CreateMock<T>(object constructorArgument)
            where T : class, IDisposable
        {
            object[] constructorArguments = constructorArgument == null ? new object[0] : new object[] { constructorArgument };

            var mock = new Mock<T>(constructorArguments);
            mock.CallBase = true;

            return mock;
        }
    }
}
